/**
 * 
 */
package net.thelostlands.thelostmod;

import net.thelostlands.thelostmod.runnable.Mercury;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Properties;
import java.util.logging.Logger;

import net.milkbowl.vault.permission.Permission;
import net.thelostlands.thelostmod.listeners.LMEntityListener;
import net.thelostlands.thelostmod.listeners.LMPlayerListener;
import net.thelostlands.thelostmod.listeners.LMPluginListener;
import net.thelostlands.thelostmod.runnable.ResetVisiblesForPlayer;
import net.thelostlands.thelostmod.runnable.UpdateInvisibilityTask;

import org.bukkit.command.CommandExecutor;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event.Type;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.config.Configuration;

/**
 * @author sleaker
 *
 */
public class LostMod extends JavaPlugin {

    protected static final Logger log = Logger.getLogger("Minecraft");
    private LMPlayerListener playerListener = new LMPlayerListener(this);
    private LMEntityListener entityListener = new LMEntityListener(this);
    private LMPluginListener pluginListener = new LMPluginListener(this);
    private final LMPacketManager packetManager = new LMPacketManager();
    public PermHandler adminHandler;
    public CommandExecutor cmdExec;
    public static boolean useSpout = false;
    public static final String logPrefix = "[TLLL] ";
    public static final String mainDirectory = "plugins" + File.separator + "TheLostMod";
    public static File messageConfig = new File(mainDirectory + File.separator + "messageConfig.yml");
    public static Permission perms;
    public static final String plugName = "[TheLostMod]";
    public static final String playerDataPath = mainDirectory + File.separator + "players/";
    public static Properties prop = new Properties();
    Configuration globalConfig;
    public Mercury mercury;

    @Override
    public void onDisable() {
        log.info(plugName + " - Disabled!");
    }

    @Override
    public void onEnable() {
        //Setup Permissions 
        if (!setupDependencies()) {
            log.warning(plugName + " - Non ho trovato nessuno plugin Permission, esco.");
            getServer().getPluginManager().disablePlugin(this);
            return;
        }

        setupOptionals();

        //Make our directories.
        File dir = new File(playerDataPath);
        //Register our events
        PluginManager pm = getServer().getPluginManager();
        pm.registerEvent(Type.PLAYER_JOIN, playerListener, Priority.Highest, this);
        pm.registerEvent(Type.PLAYER_QUIT, playerListener, Priority.Highest, this);
        pm.registerEvent(Type.PLAYER_TELEPORT, playerListener, Priority.Highest, this);
        pm.registerEvent(Type.PLAYER_PICKUP_ITEM, playerListener, Priority.Highest, this);
        pm.registerEvent(Type.ENTITY_DAMAGE, entityListener, Priority.Highest, this);
        pm.registerEvent(Type.ENTITY_COMBUST, entityListener, Priority.Highest, this);
        pm.registerEvent(Type.ENTITY_TARGET, entityListener, Priority.Highest, this);
        pm.registerEvent(Type.PLUGIN_ENABLE, pluginListener, Priority.Monitor, this);
        pm.registerEvent(Type.PLUGIN_DISABLE, pluginListener, Priority.Monitor, this);

        adminHandler = new PermHandler(this);
        //Register our commands
        cmdExec = new CmdHandler(this);
        getCommand("stealth").setExecutor(cmdExec);
        getCommand("vanish").setExecutor(cmdExec);
        getCommand("admin").setExecutor(cmdExec);
        getCommand("god").setExecutor(cmdExec);
        getCommand("return").setExecutor(cmdExec);
        getCommand("saveloc").setExecutor(cmdExec);
        getCommand("adminstatus").setExecutor(cmdExec);
        getCommand("admin_put").setExecutor(cmdExec);
        getCommand("admin_bring").setExecutor(cmdExec);
        getCommand("admin_tp").setExecutor(cmdExec);
        getCommand("admin_heal").setExecutor(cmdExec);
        getCommand("setmessage").setExecutor(cmdExec);
        getCommand("getmessage").setExecutor(cmdExec);
        //If this was a reload lets make sure to reload all of our players data
        for (Player player : this.getServer().getOnlinePlayers()) {
            loadPlayer(player);
        }
        mercury = new Mercury(this);
        if (!messageConfig.exists()) {

            try {
                getServer().getLogger().warning("Provo a creare il file");
                messageConfig.createNewFile();
                getServer().getLogger().warning("File creato");
                FileOutputStream output = new FileOutputStream(messageConfig);
                prop.put(Stringhe.MSG, "Benvenuti nel server");
                prop.put("Recurring-Broadcast", "True");
                prop.put("Time-between-messages-in-seconds", "60");
                prop.store(output, "Modificate le opzioni a vostropiacimento");
                output.flush();
                output.close();
                log.info("Configuration file created. Please configure and reload it.");
                mercury.setMessage("Benvenuti nel server");
                mercury.setSeconds(60);
                
                
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } else {
            loadConfigFile();
        }
        mercury.start();

    }

    
    public void changeConfigFile(){
    	try {
    		
            FileOutputStream output = new FileOutputStream(messageConfig);            
            prop.put(Stringhe.MSG, ""+mercury.getRawMessage());
            prop.put("Time-between-messages-in-seconds", ""+mercury.getSeconds());
            prop.store(output, "Modificate le opzioni a vostro piacimento");
            output.flush();
            output.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        } 

    }

    public void loadConfigFile() {
        try {
            FileInputStream input = new FileInputStream(messageConfig);
            prop.load(input);
            String rawMessage = prop.getProperty(Stringhe.MSG);
            mercury.setRawMessage(rawMessage);
            boolean recurringMessage = Boolean.parseBoolean(prop.getProperty("Recurring-Broadcast"));
            
            int timeDelay = Integer.parseInt(prop.getProperty("Time-between-messages-in-seconds"));
            mercury.setSeconds(timeDelay);
            input.close();
            
            
        } catch (Exception ex) {
            mercury.setRawMessage("Impostare il messaggio del server");
            mercury.setSeconds(60);
            changeConfigFile();
        } 

    }

    private void setupOptionals() {
        Plugin spout = getServer().getPluginManager().getPlugin("Spout");
        if (spout != null) {
            if (spout.isEnabled()) {
                useSpout = true;
                packetManager.enable();
            }
        }
    }

    private boolean setupDependencies() {
        Collection<RegisteredServiceProvider<Permission>> allPerms = this.getServer().getServicesManager().getRegistrations(net.milkbowl.vault.permission.Permission.class);
        for (RegisteredServiceProvider<Permission> perm : allPerms) {
            Permission p = perm.getProvider();
            log.info(String.format("[%s] Trovato (Permission) %s", getDescription().getName(), p.getName()));
        }

        LostMod.perms = this.getServer().getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class).getProvider();
        log.info(String.format("[%s] Uso %s", getDescription().getName(), LostMod.perms.getName()));
        return (LostMod.perms != null);
    }

    public PermHandler getAdminHandler() {
        return adminHandler;
    }

    /**
     * @return the packetManager
     */
    public LMPacketManager getPacketManager() {
        return packetManager;
    }

    public void loadPlayer(Player player) {
        //Try to load the player object from file
        if (Permissions.hasAny(player)) {
            if (PermHandler.loadPlayer(player.getName())) {

                //Make the player go invisible if they have the toggle
                if (PermHandler.isInvisible(player.getName())) {
                    this.getServer().getScheduler().scheduleSyncDelayedTask(this, new UpdateInvisibilityTask(player, adminHandler));
                }
            }
        }

        //Makes it so players can't rejoin the server to see invisible players
        this.getServer().getScheduler().scheduleSyncDelayedTask(this, new ResetVisiblesForPlayer(player, adminHandler));
    }
}
